package com.gjy.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * AIO 测试
 *
 * @author 宫静雨
 * @version 1.0
 * @since 2023-05-17 16:37:56
 */
public class AioTest {

    public static void main(String[] args) throws IOException {
        // 创建一个异步文件通道
        Path filePath = Paths.get("D:\\code\\java\\special-topic\\encryption\\file-channel.txt");
        AsynchronousFileChannel channel = AsynchronousFileChannel.open(filePath);

        // 异步读取文件
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        long position = 0;
        Future<Integer> future = channel.read(buffer, position);
        try {
            int bytesRead = future.get();
            buffer.flip();

            String content = StandardCharsets.UTF_8.decode(buffer).toString();
            System.out.println(content);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 创建一个异步服务器套接字通道
        AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();
        serverChannel.bind(new InetSocketAddress("localhost", 8080));

        // 异步等待客户端连接
        serverChannel.accept(null, new ServerCompletionHandler(serverChannel));
    }

    static class ServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {

        private final AsynchronousServerSocketChannel serverChannel;

        public ServerCompletionHandler(AsynchronousServerSocketChannel serverChannel) {
            this.serverChannel = serverChannel;
        }

        @Override
        public void completed(AsynchronousSocketChannel clientChannel, Void attachment) {
            // 处理客户端连接成功事件
            // 读取客户端发送的数据
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            clientChannel.read(buffer, buffer, new ClientCompletionHandler(clientChannel));
            // 继续等待下一个客户端连接
            serverChannel.accept(null, this);
        }

        @Override
        public void failed(Throwable exc, Void attachment) {
            // 处理服务器启动失败事件
            exc.printStackTrace();
        }
    }

    static class ClientCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {

        private final AsynchronousSocketChannel clientChannel;

        public ClientCompletionHandler(AsynchronousSocketChannel clientChannel) {
            this.clientChannel = clientChannel;
        }

        @Override
        public void completed(Integer bytesRead, ByteBuffer buffer) {
            // 处理客户端发送数据事件
            buffer.flip();
            String content = StandardCharsets.UTF_8.decode(buffer).toString();
            System.out.println("读取到的数据：" + content);
            // 回写数据到客户端
            ByteBuffer responseBuffer = ByteBuffer.wrap("Hello, Client".getBytes());
            clientChannel.write(responseBuffer);
        }

        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
            // 处理客户端连接失败事件
            exc.printStackTrace();
        }
    }

}
